package Controller

import (
	"encoding/json"
	"fmt"
	"github.com/gin-gonic/gin"
	"gorm.io/gorm"
	"log"
	"m/Global"
	"m/model"
	"math/rand"
	"net/http"
	"strconv"
	"time"
)

func RegisterCourss(context *gin.Context) {
	// 使用结构体来获取参数
	var requestCourse = model.Course{}
	json.NewDecoder(context.Request.Body).Decode(&requestCourse)
	fmt.Println("获取到的数据：",
			requestCourse.Cno,
			requestCourse.Cname,
			requestCourse.Cclasstime,
			requestCourse.Ccycle,
			requestCourse.Camount,
			requestCourse.Caddress,
			requestCourse.Tno,
			requestCourse.Cneed,
			requestCourse.Cjoin,
		)
	// 获取参数
	fmt.Println("开始获取课程参数...")
	cno := requestCourse.Cno
	cname := requestCourse.Cname
	cclasstime := requestCourse.Cclasstime
	ccycle := requestCourse.Ccycle
	camount := requestCourse.Camount
	caddress := requestCourse.Caddress
	tno := requestCourse.Tno
	cneed := requestCourse.Cneed
	cjoin := requestCourse.Cjoin
	//cno := context.PostForm("cno")
	//cname := context.PostForm("cname")
	//cclasstime := context.PostForm("cclasstime")
	//fmt.Println("classtime=", cclasstime)
	//ccycle := context.PostForm("ccycle")
	//fmt.Println("ccycle=", ccycle)
	//camount := context.PostForm("camount")
	//caddress := context.PostForm("caddress")
	//tno := context.PostForm("tno")
	//cneed := context.PostForm("cneed")
	//cjoin := context.PostForm("cjoin")
	// 数据验证
	fmt.Println("开始验证课程数据...")
	if len(cno) == 0 {
		//context.JSON(http.StatusUnprocessableEntity, gin.H{"code":422, "msg":"课程号不可为空！"})
		fmt.Println("发现课程号为空")
		context.JSON(200, gin.H{
			"code":200,
			"msg":"课程号不能为空",
		})
		return
	}
	if len(cname) == 0 {
		//context.JSON(http.StatusUnprocessableEntity, gin.H{"code":423, "msg":"课程名不可为空！"})
		fmt.Println("发现课程名为空")
		context.JSON(200, gin.H{
			"code":200,
			"msg":"课程名不能为空",
		})
		return
	}
	if len(tno) == 0 {
		//context.JSON(http.StatusUnprocessableEntity, gin.H{"code":424, "msg":"教师名不可为空！"})
		fmt.Println("发现教师名为空")
		context.JSON(200, gin.H{
			"code":200,
			"msg":"教师名不能为空",
		})
		return
	}
	fmt.Println(cno, cname, cclasstime, ccycle, camount, caddress, tno, cneed, cjoin)
	log.Println(cno, cname, cclasstime, ccycle, camount, caddress, tno, cneed, cjoin)
	// 判断课程号是否存在
	var err error
	//var tempCno, tempCamount, tempTno, tempCneed, tempCjoin int
	//tempCno, err = strconv.Atoi(cno)
	//tempCamount, err = strconv.Atoi(camount)
	//tempTno, err = strconv.Atoi(tno)
	//tempCneed, err = strconv.Atoi(cneed)
	//tempCjoin, err = strconv.Atoi(cjoin)
	if isCnoExists(Global.Db, cno) == true {
		//context.JSON(http.StatusUnprocessableEntity, gin.H{"code":425, "msg":"课程号已经存在！"})
		context.JSON(200, gin.H{
			"code":200,
			"msg":"课程号已存在",
		})
		// 直接返回，不执行下面的create了
		return
	}
	if isTnoExists(Global.Db, tno) == false {
		//context.JSON(http.StatusUnprocessableEntity, gin.H{"code":426, "msg":"未找到这个老师！！"})
		context.JSON(200, gin.H{
			"code":200,
			"msg":"未找到这个老师",
		})
		// 直接返回，不执行下面的create了
		return
	}
	// 创建课程
	if err != nil {
		fmt.Println("错误")
		return
	}
	newCourse := model.Course{
		Cno:cno,
		Cname: cname,
		Cclasstime: cclasstime,
		Ccycle: ccycle,
		Camount: camount,
		Caddress: caddress,
		Tno: tno,
		Cneed: cneed,
		Cjoin: cjoin,
	}
	fmt.Println("newCourse:", newCourse.Cno, newCourse.Cname, newCourse.Cclasstime,newCourse.Ccycle, newCourse.Camount, newCourse.Caddress, newCourse.Tno, newCourse.Cneed, newCourse.Cjoin)
	Global.Db.Create(&newCourse)
	// 返回结果
	context.JSON(200, gin.H{
		"msg":"插入课程成功",
	})
}

func ShowCourse(context *gin.Context) {
	fmt.Println("进入showcourse")
	var course []model.Course
	err := Global.Db.Find(&course).Error
	if err != nil {
		fmt.Println("查询全体课程出错！")
		return
	}
	fmt.Println("数据库查到的全体课程信息：", course)
	context.JSON(http.StatusOK, course)
}

func CountCourse(context *gin.Context)  {
	// 调用存储过程
	var count int
	Global.Db.Raw("select count_course()").First(&count)
	fmt.Println("课程数量：", count)
	context.JSON(200, gin.H{
		"code":200,
		"msg":"返回课程数量成功",
		"data":count,
	})
	//context.JSON(http.StatusOK, count)
}

func EditCourse(context *gin.Context)  {
	fmt.Println("进入editcourse")
	var requestCourse = model.Course{}
	json.NewDecoder(context.Request.Body).Decode(&requestCourse)
	fmt.Println("即将编辑课程号：", requestCourse)

	if len(requestCourse.Cno) < 1 {
		fmt.Println("课程号不能为空！", len(requestCourse.Tno))
		context.JSON(200, gin.H{
			"code":200,
			"msg":"课程号不能为空",
		})
		return
	}
	if len(requestCourse.Cname) < 1 {
		fmt.Println("课程名不能为空！", len(requestCourse.Cname))
		context.JSON(200, gin.H{
			"code":200,
			"msg":"课程名不能为空",
		})
		return
	}
	if len(requestCourse.Cclasstime) < 1 {
		fmt.Println("上课时间不能为空！", len(requestCourse.Cclasstime))
		context.JSON(200, gin.H{
			"code":200,
			"msg":"上课时间不能为空",
		})
		return
	}
	if len(requestCourse.Ccycle) < 1 {
		fmt.Println("课程周期不能为空！", len(requestCourse.Ccycle))
		context.JSON(200, gin.H{
			"code":200,
			"msg":"课程周期不能为空",
		})
		return
	}
	if len(requestCourse.Camount) < 1 {
		fmt.Println("课程费用不能为空！", len(requestCourse.Camount))
		context.JSON(200, gin.H{
			"code":200,
			"msg":"课程费用不能为空",
		})
		return
	}
	if len(requestCourse.Caddress) < 1 {
		fmt.Println("上课教室不能为空！", len(requestCourse.Caddress))
		context.JSON(200, gin.H{
			"code":200,
			"msg":"上课教室不能为空",
		})
		return
	}
	if len(requestCourse.Cneed) < 1 {
		fmt.Println("课程所需人数不能为空！", len(requestCourse.Cneed))
		context.JSON(200, gin.H{
			"code":200,
			"msg":"课程所需人数不能为空",
		})
		return
	}
	if len(requestCourse.Cjoin) < 1 {
		fmt.Println("已报名人数不能为空！", len(requestCourse.Cjoin))
		context.JSON(200, gin.H{
			"code":200,
			"msg":"已报名人数不能为空",
		})
		return
	}



	// 课程号是否存在
	var course model.Course
	Global.Db.Where("cno = ?", requestCourse.Cno).First(&course)
	fmt.Println("course.Cno=", course.Cno)
	if course.Cno == "" {
		context.JSON(200, gin.H{
			"code":200,
			"msg":"找不到此课程",
		})
		return
	}
	// 教师号是否存在
	var teacher model.Teacher
	Global.Db.Where("tno = ?", requestCourse.Tno).First(&teacher)
	fmt.Println("teacher.Tno=", teacher.Tno)
	if teacher.Tno == "" {
		context.JSON(200, gin.H{
			"code":200,
			"msg":"找不到此教师",
		})
		return
	}

	err := Global.Db.Where("cno = ?", requestCourse.Cno).Updates(&requestCourse).Error
	if err != nil {
		fmt.Println("更新课程出错")
		context.JSON(200, gin.H{
			"code":200,
			"msg":"更新课程出错",
		})
		return
	}

	context.JSON(200, gin.H{
		"code":200,
		"msg":"更新成功",
	})
}

func DeleteCourse(context *gin.Context)  {
	fmt.Println("进入deletecourse")
	var requestCourse = model.Course{}
	json.NewDecoder(context.Request.Body).Decode(&requestCourse)
	fmt.Println("即将删除课程编号：", requestCourse.Cno)

	if len(requestCourse.Cno) < 1 {
		fmt.Println("课程号不能为空！", len(requestCourse.Cno))
		context.JSON(200, gin.H{
			"code":200,
			"msg":"课程号不能为空",
		})
		return
	}
	// 课程号是否存在
	var course model.Course
	Global.Db.Where("cno = ?", requestCourse.Cno).Find(&course)
	fmt.Println("course.Cno=", course.Cno)
	if course.Cno == "" {
		context.JSON(200, gin.H{
			"code":200,
			"msg":"找不到此课程",
		})
		return
	}
	err := Global.Db.Where("cno = ?", requestCourse.Cno).Delete(&course).Error
	if err != nil {
		context.JSON(200, gin.H{
			"code":200,
			"msg":"删除课程出错",
		})
		return
	}

	context.JSON(200, gin.H{
		"code":200,
		"msg":"删除成功",
	})
}

func isCnoExists(db *gorm.DB, cno string) bool {
	var course model.Course
	err := db.Where("cno = ?", cno).Find(&course).Error
	if err != nil {
		fmt.Println("err执行")
		return false
	}
	if course.Cno != "" {// 找到重复的课程号
		fmt.Println("找到重复的课程号为：", course.Cno)
		fmt.Println("课程执行了if")
		return true
	} else {
		fmt.Println("课程执行了else")
		return false
	}
}

func ChooseCourse(context *gin.Context)  {
	fmt.Println("进入choosecourse")
	var requestCourse = model.Keystudent{}
	json.NewDecoder(context.Request.Body).Decode(&requestCourse)
	fmt.Println("请求的学号：", requestCourse.Sno, "请求的课号：", requestCourse.Cno)
	//Global.Sno = requestCourse.Sno
	fmt.Println("global.Sno = ", Global.Sno)
	fmt.Println("查询即将选择的课程是否存在", requestCourse.Cno)

	// 学号不能为空
	if len(requestCourse.Sno) < 1 {
		fmt.Println("学号不能为空！", len(requestCourse.Sno))
		context.JSON(200, gin.H{
			"code":200,
			"msg":"学号不能为空",
		})
		return
	}

	// 只能给自己选课
	if Global.Sno != requestCourse.Sno {
		fmt.Println("只能给自己选课！")
		context.JSON(200, gin.H{
			"code":200,
			"msg":"只能给自己选课",
		})
		return
	}

	// 课号不能为空
	if len(requestCourse.Cno) < 1 {
		fmt.Println("课程号不能为空！", len(requestCourse.Cno))
		context.JSON(200, gin.H{
			"code":200,
			"msg":"课号不能为空",
		})
		return
	}

	// 课程号是否存在
	var course model.Course
	Global.Db.Where("cno = ?", requestCourse.Cno).Find(&course)
	fmt.Println("course.Cno=", course.Cno)
	if course.Cno == "" {
		context.JSON(200, gin.H{
			"code":200,
			"msg":"找不到此课程",
		})
		return
	}
	// 是否已选此课程
	var temp model.Keystudent
	//temp.Cno = requestCourse.Cno
	Global.Db.Where("cno = ? and sno = ?", requestCourse.Cno, Global.Sno).Find(&temp)
	if temp.Cno == requestCourse.Cno {
		fmt.Println("已选过此课程！")
		context.JSON(200, gin.H{
			"code":200,
			"msg":"已选过此课程",
		})
		return
	}

	// 课余量是否充足
	tempJoin, err := strconv.Atoi(course.Cjoin)
	if err != nil {
		fmt.Println("类型转换出错")
		return
	}
	tempNeed, err := strconv.Atoi(course.Cneed)
	if tempJoin == tempNeed {
		context.JSON(200, gin.H{
			"code":200,
			"msg":"课余量不足",
		})
		return
	} else {
		tempJoin++
		course.Cjoin = strconv.Itoa(tempJoin)
	}
	// 把课程状况写入数据库
	 correct := model.Course{
		Cno: course.Cno,
		Cname: course.Cname,
		Cclasstime: course.Cclasstime,
		Ccycle: course.Ccycle,
		Camount: course.Camount,
		Caddress: course.Caddress,
		Tno: course.Tno,
		Cneed: course.Cneed,
		Cjoin: course.Cjoin,
	}
	Global.Db.Where("tno = ?", requestCourse.Cno).Updates(&correct)



	// 向选课表插入数据
	newKeystudent := model.Keystudent{
		Sno: requestCourse.Sno,
		Cno: requestCourse.Cno,
	}
	fmt.Println("选课学生的学号：", newKeystudent.Sno, "课号：", newKeystudent.Cno)
	Global.Db.Create(&newKeystudent)

	context.JSON(http.StatusOK, gin.H{
		"code":200,
		"msg":"选课成功",
	})

	// 向账目表插入数据
	tNow := time.Now()
	timeNow := tNow.Format("2006-01-02 15:04:05")
	newAccount := model.Account{
		Cno: newKeystudent.Cno,
		Sno: newKeystudent.Sno,
		Adate:timeNow,
		Aclass: strconv.Itoa(GenerateRangeNum(1,10)),
		Aamount: "",
	}
	Global.Db.Create(&newAccount)

}

// GenerateRangeNum 生成一个区间范围的随机数
func GenerateRangeNum(min, max int) int {
	rand.Seed(time.Now().Unix())
	randNum := rand.Intn(max - min)
	randNum = randNum + min
	fmt.Printf("rand is %v\n", randNum)
	return randNum
}

func MyCourseCount(context *gin.Context)  int64{
	// 根据登陆的学号查询已选课程
	fmt.Println("即将查询此学生的课程：", Global.Sno)
	var myCourse []model.Keystudent
	var count int64// 返回此学生的选课数量
	Global.Db.Where("sno = ?", Global.Sno).Find(&myCourse).Count(&count)
	fmt.Println("长度：", count)
	return count
}

func MyCourse(context *gin.Context)  {
	// 根据登陆的学号查询已选课程
	fmt.Println("即将查询此学生的课程：", Global.Sno)
	//var myCourse []model.Keystudent

	//err := Global.Db.Where("sno = ?", Global.Sno).Find(&myCourse).Error
	//Global.Db.Joins("JOIN Courses ON Courses.cno = Keystudents.cno and Courses.sno = ?", Global.Sno).Joins(
	//	"JOIN KeyStudents ON Keystudent")
	//err := Global.Db.Where("cno = ?", Global.Db.Select("cno").Where("sno = ?", Global.Sno).Find(&myCourse)).Find(myCourse2).Error

	//var myCourse2 []model.StudentCourse
	//err := Global.Db.Table("courses").Select("courses.cno, courses.cname, courses.ccycle, courses.camount, courses.caddress, courses.tno, accounts.aamount").Joins("JOIN keystudents on keystudents.cno = courses.cno").Joins(
		//"JOIN accounts on accounts.sno = keystudents.sno and accounts.cno = courses.cno").Where("keystudents.sno = ?", Global.Sno).Find(&myCourse2)

	//err := Global.Db.Raw("select courses.cno, courses.cname, courses.cclasstime, courses.ccycle, courses.camount, courses.caddress, courses.tno, accounts.aamount from courses, accounts, keystudents where keystudents.sno = ? and courses.cno = keystudents.cno and accounts.sno = keystudents.sno and accounts.cno = courses.cno", Global.Sno)



	//var myCourse3 []model.Account
	////err := Global.Db.Select("keystudents.cno, accounts.aamount").Joins("JOIN keystudents on keystudents.cno = accounts.cno").Where("keystudents.sno = ?", Global.Sno).Find(&myCourse3)
	////err := Global.Db.Raw("select courses.cno, courses.cname, courses.cclasstime, courses.ccycle, courses.camount, courses.caddress, courses.tno, accounts.aamount from courses, accounts, keystudents where keystudents.sno = ? and courses.cno = keystudents.cno and accounts.sno = keystudents.sno and accounts.cno = courses.cno", Global.Sno).Find(&myCourse2)
	//err := Global.Db.Raw("select keystudents.cno, accounts.aamount from keystudents, accounts where keystudents.cno = accounts.cno and keystudents.sno = ?", Global.Sno).Find(&myCourse3)
	//if err != nil {//???
	//	context.JSON(http.StatusBadRequest, gin.H{
	//		"code":420,
	//		"msg":"查询出错",
	//	})
	//	fmt.Println("error!")
	//	//return
	//}
	//fmt.Println("myCourse2:", myCourse3)
	//context.JSON(http.StatusOK, myCourse3)

	var myCourse []model.Keystudent
	err := Global.Db.Where("sno = ?", Global.Sno).Find(&myCourse).Error
	if err != nil {
		fmt.Println("查询出错！")
		context.JSON(200, gin.H{
			"code":200,
			"msg":"查询出错",
		})
		return
	}
	context.JSON(http.StatusOK, myCourse)

}

func DeleteMyCourse(context *gin.Context) {
	// 根据登陆的学号删除课程
	//fmt.Println("即将删除此学生的课程：", Global.Sno)
	//var requestCourseNo int
	//json.NewDecoder(context.Request.Body).Decode(&requestCourseNo)
	//fmt.Println("删除课号为：", requestCourseNo)
	//var course model.Keystudent
	//course.Cno = strconv.Itoa(requestCourseNo)
	//err := Global.Db.Where("cno = ?", strconv.Itoa(requestCourseNo)).Where("sno = ?", Global.Sno).Delete(&course).Error
	//if err != nil {
	//	fmt.Println("删除出错")
	//	context.JSON(200, gin.H{
	//		"code":200,
	//		"msg":"删除出错",
	//	})
	//	return
	//}
	//context.JSON(200, gin.H{
	//	"code":200,
	//	"msg":"删除成功",
	//})

	fmt.Println("即将删除此学生的课程：", Global.Sno)
	requestCno := make(map[string]interface{})
	var course model.Keystudent
	context.ShouldBind(&requestCno)
	fmt.Println("删除的课号", requestCno["cno"])
	course.Cno = requestCno["cno"].(string)
	err := Global.Db.Where("sno = ?", Global.Sno).Where("cno = ?", course.Cno).Delete(&course).Error
	if err != nil {
		context.JSON(200, gin.H{
			"code":200,
			"msg":"删除选课表错误",
		})
		return
	}

	// 同时删除账目表的记录
	var account model.Account
	err = Global.Db.Where("sno = ?", Global.Sno).Where("cno = ?", course.Cno).Delete(&account).Error
	if err != nil {
		context.JSON(200, gin.H{
			"code":200,
			"msg":"删除账目表错误",
		})
	}
	context.JSON(200, gin.H{
		"code":200,
		"msg":"删除成功",
	})
}

func MyCourse2(context *gin.Context)  {
	// 根据登陆的学号查询已选课程
	fmt.Println("即将查询此学生的课程：", Global.Sno)
	var myCourse []model.Keystudent
	var count int64// 返回此学生的选课数量
	Global.Db.Where("sno = ?", Global.Sno).Find(&myCourse).Count(&count)
	fmt.Println("长度：", count)
	//return count

	//var count = MyCourseCount(context)
	// 定义返回给前端的临时结构体
	var tempCourse = [...]model.TempCourseSchedule{}
	var i int64
	for i = 0; i < count; i++ {
		fmt.Println("循环", i+1)
		var myCourse2 model.Course
		Global.Db.Where("cno = ?", myCourse[i].Cno).Find(&myCourse2)
		fmt.Println("aaaaaaa")
		tempCourse[i].Cno = myCourse2.Cno
		tempCourse[i].Cname = myCourse2.Cname
		tempCourse[i].Cclasstime = myCourse2.Cclasstime
		tempCourse[i].Ccycle = myCourse2.Ccycle
		tempCourse[i].Camount = myCourse2.Camount
		tempCourse[i].Caddress = myCourse2.Caddress
		tempCourse[i].Tno = myCourse2.Tno
		fmt.Println("bbbbbbb")
		//tempCourse[i].State =
	}
	//Global.Db.Where("cno = ?", myCourse.Cno).Find(&myCourse2)
	fmt.Println("mycourse:", myCourse)
	fmt.Println("tempcourse:", tempCourse)



}

